package com.happycat.metadatasource;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import javax.servlet.http.HttpServletRequest;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.access.SecurityConfig;
import org.springframework.security.web.FilterInvocation;
import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.stereotype.Component;

import com.happycat.mobile.model.AccountRole;
import com.happycat.mobile.model.UserMenu;
import com.happycat.mobile.service.AccountRoleService;
import com.happycat.mobile.service.UserMenuService;

@Component
public class HappyCatFilterInvocationSecurityMetadataSource implements FilterInvocationSecurityMetadataSource {

	@Autowired
	private AccountRoleService accountRoleService;

	@Autowired
	private UserMenuService userMenuService;

	private static Map<String, Collection<ConfigAttribute>> map = null;

	/**
	 * 获取每个资源（url）所需要的权限（角色）集合 这里应该从数据库中动态查询，这里为了方便而直接创建
	 */
	private void getResourcePermission() {
		map = new ConcurrentHashMap<String, Collection<ConfigAttribute>>();
		/**
		 * 设置资源（url）所需要的权限（角色）集合
		 */
		List<UserMenu> list = userMenuService.getMenuMappingRoleList();
		if(list != null && list.size() > 0) {
			for (UserMenu userMenu : list) {
				List<ConfigAttribute> roleList = new ArrayList<ConfigAttribute>();
				for (AccountRole accountRole : userMenu.getAccountRoleList()) {
					ConfigAttribute role = new SecurityConfig(accountRole.getRoleName());
					roleList.add(role);
				}
				map.put(userMenu.getUrl(), roleList);
			}
		}
	}

	/**
	 * 获取用户请求的某个具体的资源（url）所需要的权限（角色）集合
	 * 
	 * @param object 包含了用户请求的request信息
	 */
	@Override
	public Collection<ConfigAttribute> getAttributes(Object object) throws IllegalArgumentException {
		if (map == null) {
			getResourcePermission();
		}
		HttpServletRequest request = ((FilterInvocation) object).getHttpRequest();

		/**
		 * 遍历每个资源（url），如果与用户请求的资源（url）匹配，则返回该资源（url）所需要的权限（角色）集合，
		 * 如果全都不匹配，则表示用户请求的资源（url)不需要权限（角色）即可访问
		 */
		Iterator<String> iter = map.keySet().iterator();
		while (iter.hasNext()) {
			String url = iter.next();
			if (new AntPathRequestMatcher(url).matches(request)) {
				return map.get(url);
			}
		}
		return null;
	}

	@Override
	public Collection<ConfigAttribute> getAllConfigAttributes() {
		List<AccountRole>  accountRoleList = accountRoleService.list();
		List<ConfigAttribute> roleList = new ArrayList<ConfigAttribute>();
		for (AccountRole accountRole : accountRoleList) {
			ConfigAttribute role = new SecurityConfig(accountRole.getRoleName());
			roleList.add(role);			
		}
		return roleList;
	}

	@Override
	public boolean supports(Class<?> clazz) {
		return true;
	}
}
